package com.wzy.jpademo1.dao;

import com.wzy.jpademo1.pojo.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Map;

public interface StudentRepository extends JpaRepository<Student,Integer> {

    /**
     * 通过学生姓名来查询学生对象
     * 此方法相当于JPQL语句代码:select s from Student s where s.name = ?1
     * @param name 参数
     * @return Student对象
     */
    Student findByName(String name);

    /**
     * 通过名字和地址查询学生信息
     * 此方法相当于JPQL语句代码:select s from Student s where s.name = ?1 and s.address=?2
     * @param name
     * @param address
     * @return 包含Student对象的List集合
     */
    List<Student> findByNameAndAddress(String name,String address);

    /**
     * 通过学生姓名模糊查询学生信息
     * 此方法相当于JPQL语句代码:select s from Student s where s.name like ?1
     * @param name 参数
     * @return 包含Student对象的List集合
     */
    List<Student> findByNameLike(String name);

    /**
     * 根据班级名称查询该班级的学生信息
     * 相当于JPQL语句：select s from Student s where s.clazz.name = ?1
     * @param clazzName
     * @return
     */
    List<Student> findByClazz_Name(String clazzName);

    /**
     * 注解Query的写法
     * 根据班级名称查询该班级的学生信息
     * ?1表示第一个参数
     * 此写法与findByClazz_Name()方法实现的功能相同
     * @param clazzName
     * @return
     */
    @Query("select s from Student s where s.clazz.name = ?1")
    List<Student> findStudentsByClazzName(String clazzName);

    /**
     * 使用@Query注解的形式，查询某个班级下所有学生的姓名和性别
     * @param clazzName
     */
    @Query("select new Map(s.name as name , s.sex as sex) "
            + "from Student s where s.clazz.name = ?1")
    List<Map<String, Object>> findNameAndSexByClazzName(String clazzName);

    /**
     *  使用@Query注解的形式，查询某个班级下某种性别的所有学生的姓名
     *  上面方法是用的是参数的位置来查询的，Spring Data JPA中还支持用
     *  名称来匹配查询使用格式 “:参数名称” 引用
     * @param clazzName
     */
    @Query("select s.name from Student s "
            + "where s.clazz.name = :clazzName and s.sex = :sex ")
    List<String> findNameByClazzNameAndSex(@Param("clazzName")String clazzName , @Param("sex")char sex);

    /**
     *  使用@Query注解的形式，查询某个学生属于哪个班级
     * @param stuName
     */
    @Query("select c.name from Clazz c inner join c.students s "
            + "where s.name = ?1 ")
    String findClazzNameByStuName(String stuName);

    /**
     * 执行更新查询，使用@Query与@Modifying可以执行更新操作
     * 例如删除牛魔王这个学生
     * */
    @Modifying
    @Query("delete from Student s where s.name = ?1")
    int deleteStuByName(String stuName);
}
